package com.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description:
 * @Author: LiangJiawen
 * @Create Date Time: 2021/4/28 14:08.
 * @Update Date Time: 
 * @see
 */
public class Center {

    public static ConcurrentHashMap<String, Class> service = new ConcurrentHashMap<>();

    /**
     * 注册
     *
     *
     * @param commonService
     * @param port
     * @throws Exception
     */
    public static void regist(HashMap<String, Class> commonService, int port) throws Exception {
        service.putAll(commonService);
        ServerSocket serverSocket = new ServerSocket(port);
//        while (true){
//            new Thread(()->{
                Socket socket = null;
                try {
                    socket = serverSocket.accept();

                    ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
                    // 类名
                    String className = objectInputStream.readUTF();
                    // 方法名
                    String methodName = objectInputStream.readUTF();
                    // 参数类型
                    Class<?>[] parameterType = (Class<?>[]) objectInputStream.readObject();
                    // 参数
                    Object[] arguments = (Object[]) objectInputStream.readObject();

                    Class target = service.get(className);
                    // 反射执行
                    Method method = target.getMethod(methodName, parameterType);
                    Object result = method.invoke(target.newInstance(), arguments);

                    // 返回结果
                    ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
                    objectOutputStream.writeObject(result);
                } catch (Exception e){
                    System.out.println("处理失败！" + e.getMessage());
                } finally {
                    if (socket != null){
                        try {
                            socket.close();
                        } catch (IOException e) {
                            socket = null;
                            System.out.println("关闭异常！" + e.getMessage());
                        }
                    }
                }

//            }).start();
//        }
    }

    /**
     *  获取代理
     */
    public static <T> T getProxy (Class<T> clazz, String host, int port){
        return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[] {clazz}, (proxy, method, args) -> {

            // 采用反射，像调用本地方法一样调用远程方法
            Socket socket = new Socket(host, port);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
            objectOutputStream.writeUTF(clazz.getName());
            objectOutputStream.writeUTF(method.getName());
            objectOutputStream.writeObject(method.getParameterTypes());
            objectOutputStream.writeObject(args);

            ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
            Object result = objectInputStream.readObject();
            socket.close();
            return result;
        });
    }
}
